<?php
class Object {
	protected static $ARRAY = 1;
	protected static $BOOL = 2;
	protected static $DOUBLE = 3;
	protected static $FLOAT = 4;
	protected static $INT = 5;
	protected static $LONG = 6;
	protected static $STRING = 7;
	protected static $OTHER = 8;
	protected static $NONE = 9;
	
	/**
	 * Retorna um hashcode para este Objeto. O hashcode é um número
	 * que geralmente é diferente para diferentes Objetos. Ele é usado
	 * quando os Objetos de armazenamento em hashtables.
	 * Nota: Os hashcodes podem ser negativo, bem como positivos.
	 * 
	 * @return Integer
	 */
	public function hashCode() {
		return spl_object_hash($this);
	}
	
	/**
	 * Compara dois objetos de igualdade. Retorna um Boolean que indica se este
	 * objeto é equivalente ao objeto especificado. Este método é utilizado
	 * quando um objeto é armazenado em uma hashtable.
	 * 
	 * @param Object $object
	 * 
	 * @return Boolean
	 */
	public function equals($object) {
		return $this == $object;
	}
	
	/**
	 * Retorna o nome da classe do objeto.
	 * 
	 * @return String
	 */
	public final function getClass() {
		return get_class($this);
	}

	/**
	 * Cria um clone do Objeto. Uma nova instância é atribuída e copia é
	 * chamado para copiar o conteúdo deste Objeto para o clone.
	 * 
	 * @return Object
	 */
	public function __clone() {
		return clone $this;
	}
	
	/**
	 * Retorna uma String que representa o valor deste Objeto.
	 * Recomenda-se que todas as subclasses substituam esse método.
	 * 
	 * @return String
	 */
	public function __toString() {
		return $this->getClass() + '@' + Integer::toHexString($this->hashCode());
	}
	
	protected function type($object, $class_name = NULL) {
		if(!is_null($object)) {
			if(!is_null($class_name)) {
				if(is_a($object, $class_name)) {
					return self::$OTHER;
				} else {
					return self::$NONE;
				}
			} else  {
				// Se nao for numero
				if(is_nan($object)) {
					if(is_array($object)) {
						return self::$ARRAY;
					} else if(is_string($object)) {
						return self::$STRING;
					} else if(is_bool($object)) {
						return self::$BOOL;
					}
				} else {
					if(is_numeric($object) && is_finite($object)) {
						
					}
				}
				/*
		is_double($var)
		is_float($var)
		is_infinite($val)
		is_int($var)
		is_integer($var)
		is_long($var)
		*/
			}
		}
		
		return self::$NONE;
	}
}
?>
